import { defineStore } from "pinia";
import { computed, h, ref } from "vue";
import { ElMessage } from "element-plus";
import {
  getTradeEnabledApps,
  manualPreflightCheck,
  manualPlaceOrder
} from "@/api/trade";
import type { ContractData } from "@/types/contract.types";
import type { TickData } from "@/types/marketdata.types";
import {
  Direction,
  PriceType,
  Offset,
  type TradeEnabledAppInfo
} from "@/types/trade.types";
import type {
  PositionSchema,
  AccountInfoSchema,
  LogSchema
} from "@/types/account.types";
import { eventEngine } from "@/services/eventEngine";
import { EventType, type ServerSentEvent } from "@/types/sse.types";
import { useAccountAggregationStore } from "@/store/modules/accountAggregationStore";
import { addDialog } from "@/components/ReDialog";
import OrderConfirmDialog from "@/views/trade/components/OrderConfirmDialog.vue";

export const useTradeStore = defineStore("trade", () => {
  // ------------------------------- state ----------------------------------
  const apps = ref<TradeEnabledAppInfo[]>([]);
  const isLoadingApps = ref(false);
  const selectedAppKey = ref<string>("");
  // active tab of trade view, including:
  // active_orders, positions, position_analysis, orders, trades, logs
  const activeTab = ref<string>("active_orders");
  // trade_app_name|gateway_name|vt_position_id
  const selectedPositionId = ref<string | null>(null);
  const symbol = ref<string>("");
  const contract = ref<ContractData | null>(null);
  const currentToken = ref<string>("");
  const tick = ref<TickData | null>(null);
  const quantity = ref<number>(1);
  const price = ref<string>(PriceType.QUEUE);
  const isInitialized = ref(false);

  const aggregationStore = useAccountAggregationStore();

  // ------------------------------ getters ---------------------------------
  const selectedApp = computed<TradeEnabledAppInfo | null>(() => {
    if (!selectedAppKey.value) return null;
    const [tradeAppName, gatewayName] = selectedAppKey.value.split("|");
    return (
      apps.value.find(
        a => a.trade_app_name === tradeAppName && a.gateway_name === gatewayName
      ) || null
    );
  });

  const selectedPosition = computed<PositionSchema | null>(() => {
    if (!selectedPositionId.value) return null;
    const [tradeAppName, gatewayName, vtPositionId] =
      selectedPositionId.value.split("|");
    if (!tradeAppName || !gatewayName || !vtPositionId) return null;
    const acc = aggregationStore.aggregation.get(gatewayName) || null;
    return acc?.positions.get(vtPositionId) || null;
  });

  const accountInfo = computed<AccountInfoSchema | null>(() => {
    const sel = selectedApp.value;
    if (!sel) return null;
    return aggregationStore.aggregation.get(sel.gateway_name) || null;
  });

  const roundDigits = computed(() => {
    const pricetick = contract.value?.pricetick ?? 0;
    return pricetick >= 1 ? 0 : pricetick >= 0.0999999 ? 1 : 2;
  });

  const closeButtonLabel = computed(() => {
    const pos = selectedPosition.value;
    if (!pos) return "平仓";
    return pos.direction === Direction.LONG ? "卖平" : "买平";
  });
  const isCloseDisabled = computed(() => !selectedPosition.value);
  const closeDirection = computed(() => {
    const pos = selectedPosition.value;
    if (!pos) return null;
    return pos.direction === Direction.LONG ? Direction.SHORT : Direction.LONG;
  });

  // ------------------------------ actions ---------------------------------
  function derivePriceAndType() {
    const current = price.value;
    const priceTypeLabels = Object.values(PriceType);
    if (priceTypeLabels.includes(current as PriceType)) {
      return { price_type: current as PriceType, price_value: 0 };
    }
    const num = Number(current);
    const digits = roundDigits.value;
    const rounded = Number.isFinite(num) ? Number(num.toFixed(digits)) : 0;
    return { price_type: PriceType.LIMIT, price_value: rounded };
  }

  function openOrderConfirm(direction: Direction, offset: Offset) {
    if (!selectedApp.value || !contract.value) {
      ElMessage.error("请选择可交易的账户与合约");
      return;
    }
    const c = contract.value;
    const { price_type, price_value } = derivePriceAndType();
    const vol = Number(quantity.value) || 0;
    const token = currentToken.value;
    const trade_app_name = selectedApp.value.trade_app_name;
    const orderPayload = {
      symbol: c.symbol,
      exchange: c.exchange,
      direction,
      offset,
      price: price_value,
      price_type,
      volume: vol,
      token,
      trade_app_name
    };

    addDialog({
      title: "确认委托",
      width: 520,
      alignCenter: true,
      // hideFooter: true,
      sureBtnLoading: true,
      headerRenderer: ({ titleId, titleClass }) => {
        return h("div", { class: "flex-bc" }, [
          h("span", { id: titleId, class: titleClass }, "确认委托"),
          h(
            "span",
            {
              class:
                "ml-1 rounded bg-yellow-100 border border-yellow-300 px-1.5 py-0.5 font-mono text-sm text-yellow-800"
            },
            selectedApp.value?.account_name || ""
          )
        ]);
      },
      contentRenderer: () => OrderConfirmDialog,
      props: {
        order: {
          symbol: orderPayload.symbol,
          exchange: orderPayload.exchange,
          direction: orderPayload.direction,
          offset: orderPayload.offset,
          price: orderPayload.price,
          price_type: orderPayload.price_type,
          volume: orderPayload.volume,
          trade_app_name: orderPayload.trade_app_name
        },
        account_name: selectedApp.value.account_name,
        roundDigits: roundDigits.value
      },
      beforeSure: async (done, { closeLoading }) => {
        if (!orderPayload.token) {
          ElMessage.error("缺少令牌，请刷新页面后重试");
          closeLoading();
          return;
        }
        try {
          const resp = await manualPlaceOrder(orderPayload);
          if (resp?.success) {
            ElMessage.success("委托已提交");
            await doPreflight();
            done();
          } else {
            ElMessage.error(`委托提交失败: ${resp?.message || "未知错误"}`);
            await doPreflight();
            closeLoading();
          }
        } catch (e: any) {
          ElMessage.error(`委托提交失败: ${e?.message || "网络错误"}`);
          await doPreflight();
          closeLoading();
        }
      }
    });
  }

  function confirmOpenLongOrder() {
    openOrderConfirm(Direction.LONG, Offset.OPEN);
  }

  function confirmOpenShortOrder() {
    openOrderConfirm(Direction.SHORT, Offset.OPEN);
  }

  function confirmCloseOrder() {
    const dir = closeDirection.value;
    if (!dir) return;
    openOrderConfirm(dir, Offset.CLOSE);
  }

  function handleTickEvent(evt: ServerSentEvent) {
    const data = evt.data as TickData;
    if (!data || !data.symbol || !data.exchange) return;
    if (contract.value && data.symbol === contract.value.symbol) {
      tick.value = data;
    }
  }

  /**
   * set active tab to logs
   * if log event of current account with level > 20 received
   * @param evt
   */
  function handleLogEvent(evt: ServerSentEvent) {
    const data = evt.data as LogSchema;
    if (
      !data ||
      !data.level ||
      data.level <= 20 ||
      data.trade_app_name !== selectedApp.value?.trade_app_name
    )
      return;
    activeTab.value = "logs";
  }

  async function fetchApps() {
    try {
      isLoadingApps.value = true;
      const resp = await getTradeEnabledApps();
      if (!resp?.success) throw new Error(resp?.message || "获取交易账号失败");
      apps.value = Array.isArray(resp.data) ? resp.data : [];
    } catch (err: any) {
      ElMessage.error(err?.message || "获取交易账号失败");
      apps.value = [];
    } finally {
      isLoadingApps.value = false;
    }
  }

  async function doPreflight() {
    if (!selectedApp.value) return;
    const c = contract.value;
    if (!c) return;
    try {
      const resp = await manualPreflightCheck({
        symbol: c.symbol,
        exchange: c.exchange,
        invalidate_token: currentToken.value || "",
        trade_app_name: selectedApp.value.trade_app_name,
        session_id: eventEngine.sessionId
      });
      if (!resp?.success) throw new Error(resp?.message || "预检失败");
      const { is_valid, token } = resp.data || { is_valid: false };
      if (!is_valid) {
        ElMessage.error("预检失败，请检查交易权限或合约");
        currentToken.value = "";
        return;
      }
      currentToken.value = token || "";
    } catch (e: any) {
      ElMessage.error(e?.message || "预检失败");
    }
  }

  function setSelectedAppByKey(key: string | null) {
    if (!key) {
      selectedAppKey.value = "";
      // Invalidate token when no app is selected
      currentToken.value = "";
      return;
    }
    const [trade_app_name, gateway_name] = key.split("|");
    const matched = apps.value.find(
      a =>
        a.trade_app_name === trade_app_name && a.gateway_name === gateway_name
    );
    if (matched) {
      selectedAppKey.value = `${matched.trade_app_name}|${matched.gateway_name}`;
      // Switch app: token is app-scoped; clear and redo preflight for current contract
      currentToken.value = "";
      void doPreflight();
    } else {
      selectedAppKey.value = "";
      currentToken.value = "";
      ElMessage.error("该账户不可交易或不存在");
    }
  }

  /**
   * @param pos_id trade_app_name|gateway_name|vt_position_id
   */
  function setSelectedPositionId(pos_id: string | null) {
    selectedPositionId.value = pos_id;
    const [tradeAppName, gatewayName, vtPositionId] = pos_id?.split("|") || [];
    if (tradeAppName && gatewayName && vtPositionId) {
      // Sync symbol when position is selected
      const symbol = vtPositionId.split(".")[1];
      setSymbol(symbol, false);
    }
  }

  function setSymbol(sym: string, clearSelectedPositionId: boolean = true) {
    symbol.value = sym || "";
    if (clearSelectedPositionId) {
      selectedPositionId.value = null;
    }
    const { price_type } = derivePriceAndType();
    if (price_type === PriceType.LIMIT) {
      price.value = PriceType.QUEUE;
    }
  }

  function setContract(c: ContractData | null) {
    contract.value = c;
    if (c && selectedApp.value) {
      void doPreflight();
    }
  }

  function setQuantity(val: number) {
    quantity.value = val;
  }

  function init() {
    if (isInitialized.value) return;
    console.log("Initializing trade store");
    isInitialized.value = true;
    aggregationStore.init();
    if (!apps.value.length && !isLoadingApps.value) {
      void fetchApps();
    }

    // ensure single subscription
    eventEngine.off(EventType.TICK, handleTickEvent);
    eventEngine.on(EventType.TICK, handleTickEvent);
    eventEngine.on(EventType.LOG, handleLogEvent);
  }

  function teardown() {
    eventEngine.off(EventType.TICK, handleTickEvent);
    eventEngine.off(EventType.LOG, handleLogEvent);
  }

  return {
    // state
    apps,
    isLoadingApps,
    selectedAppKey,
    activeTab,
    selectedPosition,
    symbol,
    contract,
    currentToken,
    tick,
    quantity,
    price,
    // getters
    selectedApp,
    accountInfo,
    roundDigits,
    closeButtonLabel,
    isCloseDisabled,
    closeDirection,
    selectedPositionId,
    // actions
    init,
    teardown,
    fetchApps,
    doPreflight,
    setSelectedAppByKey,
    setSelectedPositionId,
    setSymbol,
    setContract,
    setQuantity,
    openOrderConfirm,
    confirmOpenLongOrder,
    confirmOpenShortOrder,
    confirmCloseOrder
  };
});
